package top.hkyzf.util;

import com.mojang.logging.LogUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.MultiPlayerGameMode;
import org.slf4j.Logger;

import java.lang.reflect.Field;

/**
 * description: 反射辅助工具类
 * @author zhufeng
 * @date 2022-8-24 23:48
 * @version 1.0
 */
public class ReflectUtils {
    /**
     * 获取一个 slf4j 日志记录器
     */
    private static final Logger LOGGER = LogUtils.getLogger();

    /**
     * 游戏模式
     */
    private static final MultiPlayerGameMode GAME_MODE = Minecraft.getInstance().gameMode;

    /**
     * 暴力模式设置属性值
     * @param fieldName 属性名字
     */
    public static Object get(String fieldName){
        if (GAME_MODE != null) {
            Class<? extends MultiPlayerGameMode> clazz = GAME_MODE.getClass();
            try {
                // getFields() 返回一个数组，其中包含反映该类对象表示的类或接口的所有可访问公共字段的字段。
                // 包括继承的字段，但是只能是 public。
                // getDeclaredFields() 返回反映由类对象表示的类或接口声明的所有字段的字段对象数组。
                // 这包括公共、受保护、默认（包）访问和专用字段，但不包括继承的字段。
                Field field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                Object rtnObj = field.get(GAME_MODE);
                Class<?> fieldType = field.getType();
                String name = field.getName();
                LOGGER.info("fieldType:{} - name:{}", fieldType, name);
                return rtnObj;
            } catch (NoSuchFieldException | IllegalAccessException e) {
                LOGGER.error("暴力获取属性值失败，原因为：", e);
            }
        }
        return null;
    }

    /**
     * 暴力模式获取破坏的方块信息
     */
    public static void set(String fieldName, Object value){
        if (GAME_MODE != null) {
            Class<? extends MultiPlayerGameMode> clazz = GAME_MODE.getClass();
            try {
                // getFields() 返回一个数组，其中包含反映该类对象表示的类或接口的所有可访问公共字段的字段。
                // 包括继承的字段，但是只能是 public。
                // getDeclaredFields() 返回反映由类对象表示的类或接口声明的所有字段的字段对象数组。
                // 这包括公共、受保护、默认（包）访问和专用字段，但不包括继承的字段。
                Field field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                field.set(GAME_MODE, value);
                Class<?> fieldType = field.getType();
                String name = field.getName();
                LOGGER.info("fieldType:{} - name:{}", fieldType, name);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                LOGGER.error("暴力设置属性值失败，原因为：", e);
            }
        }
    }
}
